package com.orkcto.springcloude.controller;

import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.orkcto.springcloude.hystrix.MyHistrixCommand;
import com.orkcto.springcloude.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
public class webController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/web/hello")
    public String hello(){

        //使用RestTemplate  调用远程springcloud 服务者提供的服务
//        return restTemplate.getForEntity("http://localhost:8080/service/hello",String.class).getBody();
        return restTemplate.getForEntity("http://01-SPRING-CLOUD-SERVICE-PROVIDER/service/hello",String.class).getBody();
    }

    @RequestMapping("/web/user")
    public String user(){

        ResponseEntity<User> responseEntity = restTemplate.getForEntity("http://01-SPRING-CLOUD-SERVICE-PROVIDER/service/user", User.class);
        int statusCodeValue = responseEntity.getStatusCodeValue();
        HttpStatus httpStatus = responseEntity.getStatusCode();
        HttpHeaders httpHeaders = responseEntity.getHeaders();
        User body = responseEntity.getBody();

        System.err.println(statusCodeValue);
        System.err.println(httpStatus);
        System.err.println(httpHeaders);
        System.err.println(body.getId()+"--"+body.getName()+"--"+body.getPhone());


        //使用RestTemplate  调用远程springcloud 服务者提供的服务
//        return restTemplate.getForEntity("http://localhost:8080/service/hello",String.class).getBody();
        return restTemplate.getForEntity("http://01-SPRING-CLOUD-SERVICE-PROVIDER/service/user",String.class).getBody();
    }



    //熔断器注解  如果发生错误的话 调用error方法
//    @HystrixCommand(fallbackMethod = "error",
//            ignoreExceptions = Exception.class,
//            commandProperties = {
//            @HystrixPrope rty(name="execution.isolation.thread.timeoutInMilliseconds",
//                    value = "1500")
//    })
    //不进行服务降级也就是 不用调用error方法  直接返回异常给用户
    //提供者返回时间超时会触发熔断    提供者产生异常这可以不触发熔断  直返回异常 ignoreExceptions = Exception.class,
    @RequestMapping("/web/Histrix")
    @HystrixCommand(fallbackMethod = "error",commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",
                    value = "1500")
    })
    public String Histrix(){

        //模拟异常
//        int i= 1 / 0;
     return restTemplate.getForEntity("http://01-SPRING-CLOUD-SERVICE-PROVIDER/service/hello",String.class).getBody();
    }

    public String error(Throwable throwable){
        //访问远程服务失败  后的逻辑就可以写在这个方法里
        System.err.println(throwable.getMessage());
        return "error";
    }

    //自定义实现服务熔断
//    @RequestMapping("/web/hystrix2")
//    public String hystrix2() throws ExecutionException, InterruptedException {
//        MyHistrixCommand myHistrixCommand = new MyHistrixCommand(com.netflix.hystrix.HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")),restTemplate);
////        同步调用   拿到返该方法执行后会等待远程的返回结果回结果该方法才返回   然后代码继续往下执行
//        String str = myHistrixCommand.execute();
//
//        //可以写一些业务逻辑   提升功能的效率
//
//        //异步调用  该方法执行后  不会马上又远程的返回结果 将来会有结果
////        Future<String> future = myHistrixCommand.queue();
////        String str = future.get();//一直去等结果  这个方法会阻塞  知道拿到结果
//        return str;
//    }
}
